﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.OleDb;
using ESRI.ArcGIS.Geometry;
using System.IO;
using System.Collections;
using ESRI.ArcGIS.esriSystem;

namespace ArcMap_AddIn_Tools
{
    public partial class SHP2SHP : Form
    {
        double m_Xtranslation;
        double m_Ytranslation;
        double m_Rotate;
        double m_Scale;


        public SHP2SHP()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            openFileDialog1.Multiselect = true; //可以选择多个文件
        }

        /// <summary>
        /// 对点进行仿射变换
        /// </summary>
        /// <param name="pPoint"></param>
        /// <param name="m_DX"></param>
        /// <param name="m_DY"></param>
        /// <param name="m_RotationAngle"></param>
        /// <param name="m_Scale"></param>
        /// <returns></returns>
        private void TransformPoint(double x, double y, ref double X, ref double Y, double m_DX, double m_DY, double m_RotationAngle, double m_Scale)
        {
            //********************************************
            //说明：采用相似变换模型（四参数变换模型）
            // X= ax - by + c
            // Y= bx + ay + d
            //*********************************************
            double A = m_Scale * Math.Cos(m_RotationAngle);
            double B = m_Scale * Math.Sin(m_RotationAngle);
            X = A * x - B * y + m_DX;
            Y = B * x + A * y + m_DY;
        }
        /// <summary>
        /// 打开计算参数按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonReadCoordinateFile_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                string coordinateFile = openFileDialog1.FileName;
                this.textBoxCoordinateFiles.Text = coordinateFile;
                CalculateParam();
                Calculate(ReadFile());
            }
        }

        private void CalculateParam()
        {
            string[] spilt = ReadFile();
            double[] FromX = new double[spilt.Length / 4];
            double[] FromY = new double[spilt.Length / 4];
            double[] ToX = new double[spilt.Length / 4];
            double[] ToY = new double[spilt.Length / 4];

            for (int i = 0; i < spilt.Length; i++)
            {
                int pointNum = i / 4;
                int spiltNum = i % 4;
                switch (spiltNum)
                {
                    case 0:
                        FromX[pointNum] = Convert.ToDouble(spilt[i]);
                        break;
                    case 1:
                        FromY[pointNum] = Convert.ToDouble(spilt[i]);
                        break;
                    case 2:
                        ToX[pointNum] = Convert.ToDouble(spilt[i]);
                        break;
                    case 3:
                        ToY[pointNum] = Convert.ToDouble(spilt[i]);
                        break;
                }
            }

            IPoint[] pFromPoints = new IPoint[spilt.Length / 4];
            IPoint[] pToPoints = new IPoint[spilt.Length / 4];
            string text = "";
            for (int i = 0; i < spilt.Length / 4; i++)
            {
                string temp = string.Format("{0},{1}--->{2},{3}\r\n", FromX[i], FromY[i], ToX[i], ToY[i]);
                text += temp;
            }

            this.textBoxInfo.Text = text;
            //string number= string.Format("总共有【{0}】个控制点！", spilt.Length / 4);
            //this.textBoxInfo.Text = string.Format("{0}\r\n{1}", text, number);
        }

        private string[] ReadFile()
        {
            string textPath = this.textBoxCoordinateFiles.Text;

            string text = null;
            StreamReader objReader = new StreamReader(textPath);
            string sLine = "";
            ArrayList arrText = new ArrayList();

            while (sLine != null)
            {
                sLine = objReader.ReadLine();
                if (sLine != null && sLine != "")
                    arrText.Add(sLine);
            }
            objReader.Close();
            foreach (string sOutput in arrText)
            {
                if (sOutput != "")
                {
                    text += sOutput;
                }
            }
            text = text.Substring(1);
            text = text.Replace("\t", "|");
            text = text.Replace("||", "|");
            string[] split = text.Split(new Char[] { '|' });//返回:{"1","2.3","","4"}stream.Split()

            return split;
        }

        private void Calculate(string[] spilt)
        {
            double[] FromX = new double[spilt.Length / 4];
            double[] FromY = new double[spilt.Length / 4];
            double[] ToX = new double[spilt.Length / 4];
            double[] ToY = new double[spilt.Length / 4];
            for (int i = 0; i < spilt.Length; i++)
            {
                int pointNum = i / 4;
                int spiltNum = i % 4;
                switch (spiltNum)
                {
                    case 0:
                        FromX[pointNum] = Convert.ToDouble(spilt[i]);
                        break;
                    case 1:
                        FromY[pointNum] = Convert.ToDouble(spilt[i]);
                        break;
                    case 2:
                        ToX[pointNum] = Convert.ToDouble(spilt[i]);
                        break;
                    case 3:
                        ToY[pointNum] = Convert.ToDouble(spilt[i]);
                        break;
                }
            }
            IPoint[] pFromPoints = new IPoint[spilt.Length / 4];
            IPoint[] pToPoints = new IPoint[spilt.Length / 4];
            for (int i = 0; i < spilt.Length / 4; i++)
            {
                pFromPoints[i] = new PointClass() { X = FromX[i], Y = FromY[i] };
                pToPoints[i] = new PointClass() { X = ToX[i], Y = ToY[i] };
            }
            //实例化仿射变换对象
            //IAffineTransformation2D3GEN tAffineTransformation = new AffineTransformation2DClass();
            IAffineTransformation2D3GEN tAffineTransformation = new AffineTransformation2DClass();
            //从源控制点定义参数
            //tAffineTransformation.DefineFromControlPoints(ref pFromPoints, ref pToPoints);
            tAffineTransformation.DefineConformalFromControlPoints(ref pFromPoints, ref pToPoints);
            string XTranslation = tAffineTransformation.XTranslation.ToString();
            string YTranslation = tAffineTransformation.YTranslation.ToString();
            string Rotation = tAffineTransformation.Rotation.ToString();
            string XScale = tAffineTransformation.XScale.ToString();
            string YScale = tAffineTransformation.YScale.ToString();
            string Scale = Math.Pow((Math.Pow(tAffineTransformation.XScale, 2) + Math.Pow(tAffineTransformation.YScale, 2)), 0.5).ToString();
            //将参数写到控件上
            this.textBoxXtranslation.Text = XTranslation;
            this.textBoxYtranslation.Text = YTranslation;
            this.textBoxRotate.Text = Rotation;
            this.textBoxScale.Text = XScale;
        }

        private void buttonOpen_Click(object sender, EventArgs e)
        {
            string inShpPath = "";
            FolderBrowserDialog outputDialog = new FolderBrowserDialog();
            if (outputDialog.ShowDialog() == DialogResult.OK)
            {
                inShpPath = outputDialog.SelectedPath;
                this.textBoxInDir.Text = inShpPath;
            }
        }

        private void buttonCreate_Click(object sender, EventArgs e)
        {
            string outShpPath = "";
            FolderBrowserDialog outputDialog = new FolderBrowserDialog();
            if (outputDialog.ShowDialog() == DialogResult.OK)
            {
                outShpPath = outputDialog.SelectedPath;
                this.textBoxOutDir.Text = outShpPath;
            }
        }
        /// <summary>
        /// 确定按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonOK_Click(object sender, EventArgs e)
        {
            DateTime beginTime = DateTime.Now;
            //给坐标平移的x，y赋值并检查有效性。
            if ((textBoxXtranslation.Text == "") || (textBoxYtranslation.Text == "") || (textBoxScale.Text == "") || (textBoxScale.Text == "")) return;
            try
            {
                m_Xtranslation = Convert.ToDouble(this.textBoxXtranslation.Text);
                m_Ytranslation = Convert.ToDouble(this.textBoxYtranslation.Text);
                m_Rotate = Convert.ToDouble(this.textBoxRotate.Text);
                m_Scale = Convert.ToDouble(this.textBoxScale.Text);
            }
            catch (Exception)
            {
                MessageBox.Show("输入的参数格式不对");
                return;
            }
            string inShpFile = this.textBoxInDir.Text;
            string outShpFile = this.textBoxOutDir.Text;

            try
            {
                DirectoryCopy(inShpFile, outShpFile, true);
            }
            catch (Exception ex)
            {
                MessageBox.Show("转换出错，可能是由于shp文件不规范引起，请用arcmap打开重新导出（EXPORT）或者重新生成一次再试。");
                return;
            }
            DateTime endTime = DateTime.Now;
            string time = GetDiffTime(beginTime, endTime);
            this.labelText.Text = "换转结束！";
            MessageBox.Show(string.Format("SHP文件转换已经完成！共进行{0}！", time));
        }

        /// <summary>
        /// 复制SHP目录
        /// </summary>
        /// <param name="sourceDirName"></param>
        /// <param name="destDirName"></param>
        /// <param name="copySubDirs"></param>
        internal void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
        {
            DirectoryInfo dir = new DirectoryInfo(sourceDirName);
            DirectoryInfo[] dirs = dir.GetDirectories();
            if (!dir.Exists)
            {
                throw new DirectoryNotFoundException(
                    "源目录不存在或者未找到："
                    + sourceDirName);
            }
            if (!Directory.Exists(destDirName))
            {
                Directory.CreateDirectory(destDirName);
            }
            FileInfo[] files = dir.GetFiles();
            foreach (FileInfo file in files)
            {
                string temppath = System.IO.Path.Combine(destDirName, file.Name);
                if (file.Name.Contains(".shx") || file.Name.Contains(".dbf"))
                {
                    file.CopyTo(temppath, false);
                }
                if (file.Name.Contains(".shp"))
                {
                    string InputFilePath = file.Directory.ToString();
                    string OutputFilePath = destDirName;
                    string fileName = file.Name.Substring(0, file.Name.IndexOf("."));
                    labelText.Text = string.Format("正在转换:{0}.shp", fileName);
                    CreateShp(InputFilePath, OutputFilePath, fileName);
                    Application.DoEvents();

                }
            }
            if (copySubDirs)
            {
                foreach (DirectoryInfo subdir in dirs)
                {
                    string temppath = System.IO.Path.Combine(destDirName, subdir.Name);
                    DirectoryCopy(subdir.FullName, temppath, copySubDirs);
                }
            }
        }

        private void buttonCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void CreateShp(string InputFile_Path, string OutputFile_Path, string fileName)
        {
            string InputShpFile_FullPath = string.Format("{0}\\{1}.shp", InputFile_Path, fileName);//input shp file
            string InputShxFile_FullPath = string.Format("{0}\\{1}.shx", InputFile_Path, fileName);//input shx file
            string OutputShpFile_FullPath = string.Format("{0}\\{1}.shp", OutputFile_Path, fileName);//output shp file
            System.IO.FileStream ws = new System.IO.FileStream(OutputShpFile_FullPath, FileMode.Create);
            BinaryWriter writer = new BinaryWriter(ws);
            byte[] b;
            int FileCode = 0;   //文件代码
            int Unused = 0;     //未使用
            int FileLength = 0; //文件长度
            int Version = 0;    //版本
            int ShapeType = 0;  //Shape类型

            double Xmin = 0;    //边界盒
            double Ymin = 0;
            double Xmax = 0;
            double Ymax = 0;
            double Zmin = 0;
            double Zmax = 0;
            double Mmin = 0;
            double Mmax = 0;

            int RecorderNumber = 0; //Shp文件的记录数
            try
            {
                //先读取.shx文件,得到文件的总字节长度 
                System.IO.FileStream fo = new System.IO.FileStream(InputShxFile_FullPath, FileMode.Open, FileAccess.Read);
                //文件流形式 
                BinaryReader bi = new BinaryReader(fo); //二进制读取文件的对象 
                FileCode = bi.ReadInt32();
                FileCode = Convert.ToInt32(big2little(FileCode));
                for (int i = 0; i < 5; i++)
                {
                    Unused = bi.ReadInt32();
                }

                FileLength = bi.ReadInt32();           //FileLength以字为单位，一字等于2字节，等于16位

                FileLength = Convert.ToInt32(big2little(FileLength));
                fo.Close();
                RecorderNumber = (int)(FileLength - 50) / 4;  //求取.shp文件的记录数

                //打开shp文件 
                if (InputShxFile_FullPath == "")
                {
                    return;
                }

                /********************
                 * 主文件头 
                  主文件头100字节长。表1显示带有字节位置，值，类型和字节顺序的文件头中的域。 
                在此表中，位置是相对于文件的开始。 
                表 1 主文件头的描述 
                位置          域                值           类型           字节顺序 
                0字节        文件代码          9994          整数              大 
                4字节        未被使用           0            整数              大 
                8字节        未被使用           0            整数              大 
                12字节       未被使用           0            整数              大 
                16字节       未被使用           0            整数              大 
                20字节       未被使用           0            整数              大 
                24字节       文件长度        文件长度        整数              大 
                28字节         版本           1000           整数              小 
                32字节       Shape类型      Shape类型       整数              小 
                36字节        边界盒          Xmin         双精度             小 
                44字节        边界盒          Ymin         双精度             小 
                52字节        边界盒          Xmax         双精度             小 
                60字节        边界盒          Ymax         双精度             小 
                68字节        边界盒          Zmin         双精度             小 
                76字节        边界盒          Zmax         双精度             小 
                84字节        边界盒          Mmin         双精度             小 
                92字节        边界盒          Mmax         双精度             小 

                ************************* */
                //打开.shp文件,读取x,y坐标的信息 
                System.IO.FileStream fs = new System.IO.FileStream(InputShpFile_FullPath, FileMode.Open, FileAccess.Read); //文件流形式 
                BinaryReader br = new BinaryReader(fs);

                FileCode = br.ReadInt32();
                writer.Write(FileCode);
                FileCode = Convert.ToInt32(big2little(FileCode));
                for (int i = 0; i < 5; i++)
                {
                    Unused = br.ReadInt32();
                    writer.Write(Unused);
                }
                FileLength = br.ReadInt32();
                writer.Write(FileLength);
                FileLength = Convert.ToInt32(big2little(FileLength));
                //int a = (int)fs.Length;
                Version = br.ReadInt32();
                ShapeType = br.ReadInt32();
                Xmin = br.ReadDouble();
                Ymin = br.ReadDouble();
                Xmax = br.ReadDouble();
                Ymax = br.ReadDouble();
                Zmin = br.ReadDouble();
                Zmax = br.ReadDouble();
                Mmin = br.ReadDouble();
                Mmax = br.ReadDouble();

                writer.Write(Version);
                writer.Write(ShapeType);
                double temp_x = 0;
                double temp_y = 0;

                TransformPoint(Xmin, Ymin, ref temp_x, ref temp_y, m_Xtranslation, m_Ytranslation, m_Rotate, m_Scale);
                writer.Write(temp_x);
                writer.Write(temp_y);
                TransformPoint(Xmax, Ymax, ref temp_x, ref temp_y, m_Xtranslation, m_Ytranslation, m_Rotate, m_Scale);
                writer.Write(temp_x);
                writer.Write(temp_y);

                writer.Write(Zmin);
                writer.Write(Zmax);
                writer.Write(Mmin);
                writer.Write(Mmax);
                // 读取坐标文件头的内容结束
                //根据几何类型读取信息
                int RecorderNum = 0;
                int ContentLength = 0;

                //读取shx索引文件，算出错误点个数
                System.IO.FileStream f_shx = new System.IO.FileStream(InputShxFile_FullPath, FileMode.Open, FileAccess.Read);
                //文件流形式 
                BinaryReader br_shx = new BinaryReader(f_shx); //二进制读取文件的对象 
                br_shx.ReadBytes(100);
                int offset;
                int last_Offset = 0; ;
                int this_Offset = 0;
                int oneRecordLength_Shx;
                int true_RecordLength = 0;
                int errorLength = 0;
                switch (ShapeType)
                {
                    case 1://single point 
                        for (int i = 0; i < RecorderNumber; i++)
                        {
                            RecorderNum = br.ReadInt32();     //记录号
                            ContentLength = br.ReadInt32();     //坐标记录长度
                            writer.Write(RecorderNum);
                            writer.Write(ContentLength);
                            RecorderNum = Convert.ToInt32(big2little(RecorderNum));
                            ContentLength = Convert.ToInt32(big2little(ContentLength));       // ContentLength以字为单位，一字等于2字节，等于16位
                            int shapetype1 = 0;
                            double x = 0;
                            double y = 0;
                            shapetype1 = br.ReadInt32();
                            writer.Write(shapetype1);
                            x = br.ReadDouble();
                            y = br.ReadDouble();
                            double X = 0;
                            double Y = 0;
                            TransformPoint(x, y, ref X, ref Y, m_Xtranslation, m_Ytranslation, m_Rotate, m_Scale);
                            writer.Write(X);
                            writer.Write(Y);
                        }
                        break;
                    case 3://Polyline layer 
                        for (int n = 0; n < RecorderNumber; n++)
                        {
                            if (n == 0)
                            {
                                offset = Convert.ToInt32(big2little(br_shx.ReadInt32()));
                                last_Offset = offset;
                            }
                            if (n < RecorderNumber - 1)
                            {
                                oneRecordLength_Shx = Convert.ToInt32(big2little(br_shx.ReadInt32()));
                                offset = Convert.ToInt32(big2little(br_shx.ReadInt32()));
                                this_Offset = offset;
                                true_RecordLength = this_Offset - last_Offset - 4;
                                last_Offset = this_Offset;

                            }
                            RecorderNum = br.ReadInt32();        //记录号
                            ContentLength = br.ReadInt32();     //坐标记录长度
                            writer.Write(RecorderNum);
                            writer.Write(ContentLength);
                            RecorderNum = Convert.ToInt32(big2little(RecorderNum));
                            ContentLength = Convert.ToInt32(big2little(ContentLength));        // ContentLength以字为单位，一字等于2字节，等于16位          
                            errorLength = 0;
                            if (true_RecordLength != ContentLength)
                            {
                                if (n != RecorderNumber - 1)
                                {
                                    errorLength = (true_RecordLength - ContentLength) * 2;
                                }
                            }
                            int shapetype1 = 0;          //几何类型
                            shapetype1 = br.ReadInt32();
                            writer.Write(shapetype1);
                            double Xmin1 = 0;    //边界盒
                            double Ymin1 = 0;
                            double Xmax1 = 0;
                            double Ymax1 = 0;
                            Xmin1 = br.ReadDouble();
                            Ymin1 = br.ReadDouble();
                            Xmax1 = br.ReadDouble();
                            Ymax1 = br.ReadDouble();

                            temp_x = 0;
                            temp_y = 0;
                            TransformPoint(Xmin1, Ymin1, ref temp_x, ref temp_y, m_Xtranslation, m_Ytranslation, m_Rotate, m_Scale);
                            writer.Write(temp_x);
                            writer.Write(temp_y);
                            TransformPoint(Xmax1, Ymax1, ref temp_x, ref temp_y, m_Xtranslation, m_Ytranslation, m_Rotate, m_Scale);
                            writer.Write(temp_x);
                            writer.Write(temp_y);

                            int Numparts;     //子线段个数
                            int Numpoints;    //坐标点数
                            Numparts = br.ReadInt32();
                            Numpoints = br.ReadInt32();
                            writer.Write(Numparts);
                            writer.Write(Numpoints);

                            int[] parts = new int[Numparts];
                            for (int i = 0; i < Numparts; i++)
                            {
                                parts[i] = br.ReadInt32();
                                writer.Write(parts[i]);
                            }
                            double[] pointsx = new double[Numpoints];
                            double[] pointsy = new double[Numpoints];
                            for (int i = 0; i < Numpoints; i++)
                            {
                                pointsx[i] = br.ReadDouble();
                                pointsy[i] = br.ReadDouble();
                                double X = 0;
                                double Y = 0;
                                TransformPoint(pointsx[i], pointsy[i], ref X, ref Y, m_Xtranslation, m_Ytranslation, m_Rotate, m_Scale);

                                writer.Write(X);
                                writer.Write(Y);
                            }
                            b = br.ReadBytes(errorLength);
                            writer.Write(b);
                        }
                        break;
                    case 5://Polygon layer 
                        for (int n = 0; n < RecorderNumber; n++)
                        {
                            if (n == 0)
                            {
                                offset = Convert.ToInt32(big2little(br_shx.ReadInt32()));
                                last_Offset = offset;
                            }
                            if (n < RecorderNumber - 1)
                            {
                                oneRecordLength_Shx = Convert.ToInt32(big2little(br_shx.ReadInt32()));
                                offset = Convert.ToInt32(big2little(br_shx.ReadInt32()));
                                this_Offset = offset;
                                true_RecordLength = this_Offset - last_Offset - 4;
                                last_Offset = this_Offset;

                            }
                            RecorderNum = br.ReadInt32();        //记录号
                            ContentLength = br.ReadInt32();     //坐标记录长度
                            writer.Write(RecorderNum);
                            writer.Write(ContentLength);
                            RecorderNum = Convert.ToInt32(big2little(RecorderNum));
                            ContentLength = Convert.ToInt32(big2little(ContentLength));        // ContentLength以字为单位，一字等于2字节，等于16位   
                            errorLength = 0;
                            if (true_RecordLength != ContentLength)
                            {
                                if (n != RecorderNumber - 1)
                                {
                                    errorLength = (true_RecordLength - ContentLength) * 2;
                                }
                            }
                            int shapetype1 = 0;          //几何类型
                            shapetype1 = br.ReadInt32();
                            writer.Write(shapetype1);
                            double Xmin1 = 0;    //边界盒
                            double Ymin1 = 0;
                            double Xmax1 = 0;
                            double Ymax1 = 0;
                            Xmin1 = br.ReadDouble();
                            Ymin1 = br.ReadDouble();
                            Xmax1 = br.ReadDouble();
                            Ymax1 = br.ReadDouble();

                            temp_x = 0;
                            temp_y = 0;
                            TransformPoint(Xmin1, Ymin1, ref temp_x, ref temp_y, m_Xtranslation, m_Ytranslation, m_Rotate, m_Scale);
                            writer.Write(temp_x);
                            writer.Write(temp_y);
                            TransformPoint(Xmax1, Ymax1, ref temp_x, ref temp_y, m_Xtranslation, m_Ytranslation, m_Rotate, m_Scale);
                            writer.Write(temp_x);
                            writer.Write(temp_y);

                            int Numparts;     //子环个数
                            int Numpoints;    //坐标点数
                            Numparts = br.ReadInt32();
                            Numpoints = br.ReadInt32();
                            writer.Write(Numparts);
                            writer.Write(Numpoints);
                            int[] parts = new int[Numparts];
                            for (int i = 0; i < Numparts; i++)
                            {
                                parts[i] = br.ReadInt32();
                                writer.Write(parts[i]);
                            }
                            double[] pointsx = new double[Numpoints];
                            double[] pointsy = new double[Numpoints];
                            for (int i = 0; i < Numpoints; i++)
                            {
                                pointsx[i] = br.ReadDouble();
                                pointsy[i] = br.ReadDouble();
                                double X = 0;
                                double Y = 0;
                                TransformPoint(pointsx[i], pointsy[i], ref X, ref Y, m_Xtranslation, m_Ytranslation, m_Rotate, m_Scale);
                                writer.Write(X);
                                writer.Write(Y);
                            }
                            b = br.ReadBytes(errorLength);
                            writer.Write(b);
                        }
                        break;
                    case 8://MultiPoint 
                        for (int n = 0; n < RecorderNumber; n++)
                        {
                            RecorderNum = br.ReadInt32();     //记录号
                            ContentLength = br.ReadInt32();     //坐标记录长度
                            writer.Write(RecorderNum);
                            writer.Write(ContentLength);
                            RecorderNum = Convert.ToInt32(big2little(RecorderNum));
                            ContentLength = Convert.ToInt32(big2little(ContentLength));       // ContentLength以字为单位，一字等于2字节，等于16位
                            int shapetype1 = 0;
                            double x = 0;
                            double y = 0;
                            shapetype1 = br.ReadInt32();
                            writer.Write(shapetype1);
                            x = br.ReadDouble();
                            y = br.ReadDouble();
                            double Xmin1 = 0;    //边界盒
                            double Ymin1 = 0;
                            double Xmax1 = 0;
                            double Ymax1 = 0;
                            Xmin1 = br.ReadDouble();
                            Ymin1 = br.ReadDouble();
                            Xmax1 = br.ReadDouble();
                            Ymax1 = br.ReadDouble();

                            temp_x = 0;
                            temp_y = 0;
                            TransformPoint(Xmin1, Ymin1, ref temp_x, ref temp_y, m_Xtranslation, m_Ytranslation, m_Rotate, m_Scale);
                            writer.Write(temp_x);
                            writer.Write(temp_y);
                            TransformPoint(Xmax1, Ymax1, ref temp_x, ref temp_y, m_Xtranslation, m_Ytranslation, m_Rotate, m_Scale);
                            writer.Write(temp_x);
                            writer.Write(temp_y);

                            int Numpoints;    //坐标点数
                            Numpoints = br.ReadInt32();
                            writer.Write(Numpoints);

                            double[] pointsx = new double[Numpoints];
                            double[] pointsy = new double[Numpoints];
                            for (int i = 0; i < Numpoints; i++)
                            {
                                pointsx[i] = br.ReadDouble();
                                pointsy[i] = br.ReadDouble();
                                double X = 0;
                                double Y = 0;
                                TransformPoint(pointsx[i], pointsy[i], ref X, ref Y, m_Xtranslation, m_Ytranslation, m_Rotate, m_Scale);
                                writer.Write(X);
                                writer.Write(Y);
                            }
                        }
                        break;

                    case 11:
                        for (int i = 0; i < RecorderNumber; i++)
                        {
                            RecorderNum = br.ReadInt32();     //记录号
                            ContentLength = br.ReadInt32();     //坐标记录长度
                            writer.Write(RecorderNum);
                            writer.Write(ContentLength);
                            int shapetype1 = 0;
                            double x = 0;
                            double y = 0;
                            shapetype1 = br.ReadInt32();
                            writer.Write(shapetype1);
                            x = br.ReadDouble();
                            y = br.ReadDouble();
                            double X = 0;
                            double Y = 0;
                            TransformPoint(x, y, ref X, ref Y, m_Xtranslation, m_Ytranslation, m_Rotate, m_Scale);
                            writer.Write(X);
                            writer.Write(Y);
                            b = br.ReadBytes(16);//Z值和M值
                            writer.Write(b);
                        }
                        break;
                    case 13://Polyline Z layer 
                        for (int n = 0; n < RecorderNumber; n++)
                        {
                            if (n == 0)
                            {
                                offset = Convert.ToInt32(big2little(br_shx.ReadInt32()));
                                last_Offset = offset;
                            }
                            if (n < RecorderNumber - 1)
                            {
                                oneRecordLength_Shx = Convert.ToInt32(big2little(br_shx.ReadInt32()));
                                offset = Convert.ToInt32(big2little(br_shx.ReadInt32()));
                                this_Offset = offset;
                                true_RecordLength = this_Offset - last_Offset - 4;
                                last_Offset = this_Offset;

                            }
                            RecorderNum = br.ReadInt32();        //记录号
                            ContentLength = br.ReadInt32();     //坐标记录长度
                            writer.Write(RecorderNum);
                            writer.Write(ContentLength);
                            RecorderNum = Convert.ToInt32(big2little(RecorderNum));
                            ContentLength = Convert.ToInt32(big2little(ContentLength));        // ContentLength以字为单位，一字等于2字节，等于16位   
                            errorLength = 0;
                            if (true_RecordLength != ContentLength)
                            {
                                if (n != RecorderNumber - 1)
                                {
                                    errorLength = (true_RecordLength - ContentLength) * 2;
                                }
                            }
                            int shapetype1 = 0;          //几何类型
                            shapetype1 = br.ReadInt32();
                            writer.Write(shapetype1);
                            double Xmin1 = 0;    //边界盒
                            double Ymin1 = 0;
                            double Xmax1 = 0;
                            double Ymax1 = 0;
                            Xmin1 = br.ReadDouble();
                            Ymin1 = br.ReadDouble();
                            Xmax1 = br.ReadDouble();
                            Ymax1 = br.ReadDouble();

                            temp_x = 0;
                            temp_y = 0;
                            TransformPoint(Xmin1, Ymin1, ref temp_x, ref temp_y, m_Xtranslation, m_Ytranslation, m_Rotate, m_Scale);
                            writer.Write(temp_x);
                            writer.Write(temp_y);
                            TransformPoint(Xmax1, Ymax1, ref temp_x, ref temp_y, m_Xtranslation, m_Ytranslation, m_Rotate, m_Scale);
                            writer.Write(temp_x);
                            writer.Write(temp_y);

                            int Numparts;     //子线段个数
                            int Numpoints;    //坐标点数
                            Numparts = br.ReadInt32();
                            Numpoints = br.ReadInt32();
                            writer.Write(Numparts);
                            writer.Write(Numpoints);

                            int[] parts = new int[Numparts];
                            for (int i = 0; i < Numparts; i++)
                            {
                                parts[i] = br.ReadInt32();
                                writer.Write(parts[i]);
                            }
                            double[] pointsx = new double[Numpoints];
                            double[] pointsy = new double[Numpoints];
                            for (int i = 0; i < Numpoints; i++)
                            {
                                pointsx[i] = br.ReadDouble();
                                pointsy[i] = br.ReadDouble();
                                double X = 0;
                                double Y = 0;
                                TransformPoint(pointsx[i], pointsy[i], ref X, ref Y, m_Xtranslation, m_Ytranslation, m_Rotate, m_Scale);
                                writer.Write(X);
                                writer.Write(Y);
                            }
                            b = br.ReadBytes(errorLength);
                            writer.Write(b);
                            b = br.ReadBytes(8 * (4 + 2 * Numpoints));
                            writer.Write(b);

                        }
                        break;
                    case 15://Polygon Z layer 
                        for (int n = 0; n < RecorderNumber; n++)
                        {
                            if (n == 0)
                            {
                                offset = Convert.ToInt32(big2little(br_shx.ReadInt32()));
                                last_Offset = offset;
                            }
                            if (n < RecorderNumber - 1)
                            {
                                oneRecordLength_Shx = Convert.ToInt32(big2little(br_shx.ReadInt32()));
                                offset = Convert.ToInt32(big2little(br_shx.ReadInt32()));
                                this_Offset = offset;
                                true_RecordLength = this_Offset - last_Offset - 4;
                                last_Offset = this_Offset;

                            }
                            RecorderNum = br.ReadInt32();        //记录号
                            ContentLength = br.ReadInt32();     //坐标记录长度
                            writer.Write(RecorderNum);
                            writer.Write(ContentLength);
                            RecorderNum = Convert.ToInt32(big2little(RecorderNum));
                            ContentLength = Convert.ToInt32(big2little(ContentLength));        // ContentLength以字为单位，一字等于2字节，等于16位
                            errorLength = 0;
                            if (true_RecordLength != ContentLength)
                            {
                                if (n != RecorderNumber - 1)
                                {
                                    errorLength = (true_RecordLength - ContentLength) * 2;
                                }
                            }
                            int shapetype1 = 0;          //几何类型
                            shapetype1 = br.ReadInt32();
                            writer.Write(shapetype1);
                            double Xmin1 = 0;    //边界盒
                            double Ymin1 = 0;
                            double Xmax1 = 0;
                            double Ymax1 = 0;
                            Xmin1 = br.ReadDouble();
                            Ymin1 = br.ReadDouble();
                            Xmax1 = br.ReadDouble();
                            Ymax1 = br.ReadDouble();

                            temp_x = 0;
                            temp_y = 0;
                            TransformPoint(Xmin1, Ymin1, ref temp_x, ref temp_y, m_Xtranslation, m_Ytranslation, m_Rotate, m_Scale);
                            writer.Write(temp_x);
                            writer.Write(temp_y);
                            TransformPoint(Xmax1, Ymax1, ref temp_x, ref temp_y, m_Xtranslation, m_Ytranslation, m_Rotate, m_Scale);
                            writer.Write(temp_x);
                            writer.Write(temp_y);

                            int Numparts;     //子环个数
                            int Numpoints;    //坐标点数
                            Numparts = br.ReadInt32();
                            Numpoints = br.ReadInt32();
                            writer.Write(Numparts);
                            writer.Write(Numpoints);
                            int[] parts = new int[Numparts];
                            for (int i = 0; i < Numparts; i++)
                            {
                                parts[i] = br.ReadInt32();
                                writer.Write(parts[i]);
                            }
                            double[] pointsx = new double[Numpoints];
                            double[] pointsy = new double[Numpoints];
                            for (int i = 0; i < Numpoints; i++)
                            {
                                pointsx[i] = br.ReadDouble();
                                pointsy[i] = br.ReadDouble();
                                double X = 0;
                                double Y = 0;

                                TransformPoint(pointsx[i], pointsy[i], ref X, ref Y, m_Xtranslation, m_Ytranslation, m_Rotate, m_Scale);

                                writer.Write(X);
                                writer.Write(Y);
                            }
                            b = br.ReadBytes(errorLength);
                            writer.Write(b);
                            b = br.ReadBytes(8 * (4 + 2 * Numpoints));
                            writer.Write(b);
                        }
                        break;
                    default:
                        break;
                }
                writer.Close();
            }
            catch (FileNotFoundException ee)
            {
                ee.ToString();
            }
        }

        protected string GetDiffTime(DateTime beginTime, DateTime endTime)
        {
            string strResout = "{0}{1}";
            //获得2时间的时间间隔秒计算  
            TimeSpan span = endTime - beginTime;
            int iTatol = Convert.ToInt32(span.TotalSeconds);

            int iMinutes = 1 * 60;
            int iHours = iMinutes * 60;
            int iDay = iHours * 24;
            int iMonth = iDay * 30;
            int iYear = iMonth * 12;

            if (iTatol > iYear)
            {
                return string.Format(strResout, iTatol / iYear, "年");
            }
            else if (iTatol > iMonth)
            {
                return string.Format(strResout, iTatol / iMonth, "月");
            }
            else if (iTatol > iDay)
            {
                return string.Format(strResout, iTatol / iDay, "天");
            }
            else if (iTatol > iHours)
            {
                return string.Format(strResout, iTatol / iHours, "小时");
            }
            else if (iTatol > iMinutes)
            {
                return string.Format(strResout, iTatol / iMinutes, "分钟");
            }
            else
            {
                return string.Format(strResout, iTatol, "秒");
            }
        }

        ulong big2little(int code)      //将big位序转换为little位序
        {
            ulong value;
            value = ((((ulong)(code) & (ulong)0x000000ffUL) << 24) | (((ulong)(code) & (ulong)0x0000ff00UL) << 8) | (((ulong)(code) & (ulong)0x00ff0000UL) >> 8) | (((ulong)(code) & (ulong)0xff000000UL) >> 24));
            return value;
        }
    }
}
